package com.glacier.yuyuan.gen.core.utils;

import com.glacier.common.core.constant.CommonConstant;
import com.glacier.common.core.constant.HttpStatusEnum;
import com.glacier.common.core.exception.BizException;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

/**
 * date 2023-01-29 15:33
 * 模板工具类
 *
 * @author glacier
 * @version 1.0.0
 */
public class TemplateUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(TemplateUtils.class);

    /**
     * 保存模板路径对应的Configuration 实例
     */
    private static final Map<String, Configuration> CONFIGURATION_MAP = new ConcurrentHashMap<>(8);

    private TemplateUtils() {
    }

    /**
     * 获取模板渲染后的内容
     *
     * @param templateDictionary 模板目录
     * @param templateName       模板名称
     * @param model              数据模型
     */
    public static String transform(String templateDictionary, String templateName, Map<String, Object> model) {
        String templateContent = "";
        if (model.isEmpty() || templateName == null || templateName.isBlank()) {
            return templateContent;
        }
        try (StringWriter sw = new StringWriter()) {
            // 渲染模板
            Template template = getConfiguration(templateDictionary)
                    .getTemplate(templateName);
            template.process(model, sw);
            templateContent = sw.toString();
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
        return templateContent;
    }

    /**
     * 根据模板路径 获取 配置实例
     *
     * @param templateDictionary 模板路径
     * @return 配置实例
     */
    public static Configuration getConfiguration(String templateDictionary) {
        return getConfiguration(templateDictionary, (cfg) -> {
        });
    }

    /**
     * 根据模板路径 获取 配置实例
     *
     * @param templateDictionary 模板路径
     * @param consumer           配置扩展消费者
     * @return 配置实例
     */
    public static Configuration getConfiguration(String templateDictionary, Consumer<Configuration> consumer) {
        File dir = new File(templateDictionary);
        if (!dir.exists() || !dir.isDirectory()) {
            LOGGER.warn("目录 {} 不存在！", templateDictionary);
            throw new BizException(HttpStatusEnum.SYSTEM_ERROR.getCode(),
                    "templateDictionary 目录不存在");
        }
        if (!CONFIGURATION_MAP.containsKey(templateDictionary)) {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("初始化配置！");
            }
            Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
            cfg.setTagSyntax(Configuration.AUTO_DETECT_TAG_SYNTAX);
            cfg.setDefaultEncoding(CommonConstant.UTF8);
            cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
            try {
                cfg.setDirectoryForTemplateLoading(dir);
                if (consumer != null) {
                    consumer.accept(cfg);
                }
                CONFIGURATION_MAP.putIfAbsent(templateDictionary, cfg);
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("初始化配置 {}！", cfg);
                }
                return cfg;
            } catch (IOException e) {
                LOGGER.error("目录 {} 不存在！", templateDictionary);
                throw new BizException(HttpStatusEnum.SYSTEM_ERROR.getCode(),
                        "templateDictionary 目录不存在", e);
            }
        }
        return CONFIGURATION_MAP.get(templateDictionary);
    }
}
